package com.example.excelimport.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.excelimport.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class CursorImportService {

    @Autowired
    private UserService userService;

    /**
     * 游标式读取导入 - 更实用的批量处理方式
     */
    public void importByCursor(String filePath, int batchSize) {
        long startTime = System.currentTimeMillis();
        AtomicInteger totalCount = new AtomicInteger(0);

        // 使用游标监听器
        AnalysisEventListener<User> listener = new AnalysisEventListener<User>() {
            private List<User> batchList = new ArrayList<>(batchSize);

            @Override
            public void invoke(User user, AnalysisContext context) {
                batchList.add(user);
                if (batchList.size() >= batchSize) {
                    // 批量保存
                    userService.batchSaveWithTransaction(new ArrayList<>(batchList));
                    totalCount.addAndGet(batchList.size());
                    batchList.clear();
                    log.info("已处理 {} 条数据", totalCount.get());
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // 处理最后一批数据
                if (!batchList.isEmpty()) {
                    userService.batchSaveWithTransaction(new ArrayList<>(batchList));
                    totalCount.addAndGet(batchList.size());
                    log.info("最后一批处理完成，共处理 {} 条数据", totalCount.get());
                }
                log.info("所有数据导入完成");
            }
        };

        try {
            EasyExcel.read(filePath, User.class, listener)
                    .sheet()
                    .headRowNumber(1)
                    .doRead();

            long endTime = System.currentTimeMillis();
            log.info("游标式导入完成，总数据量: {}，耗时: {} 秒",
                    totalCount.get(), (endTime - startTime) / 1000.0);
        } catch (Exception e) {
            log.error("导入失败", e);
            throw new RuntimeException("Excel导入失败", e);
        }
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
